package dao

import (
	"lib/structs/cap"
	"lib/structs/tables"
)

var SessionDao = new(sessionDao)

type sessionDao struct{}

// FindByHostIdAndWinId 根据主机ID和win会话ID查询活跃会话
func (d sessionDao) FindByHostIdAndWinId(hostId int64, winSesId int) (m tables.CapSession, err error) {
	err = DB.Model(&tables.CapSession{}).
		Where("host_id = ? and protocol = ? and win_session_id = ? and status != ?",
			hostId, "cap", winSesId, tables.CapSessionStatusForDestroyed).Limit(1).Find(&m).Error
	return
}
func (d sessionDao) FindPrivateHost(userId int64, clusterId int64) (host tables.CapHost, err error) {
	err = DB.Model(&tables.CapHost{}).Where("bind_user_id = ? AND cluster_id = ?", userId, clusterId).Find(&host).Error
	return
}

// SelectZeroSessionHost 查询活跃会话数为0且没有被私人绑定也没有被锁定的主机，也就是完全空闲的主机
func (d sessionDao) SelectZeroSessionHost(clusterId int64) (li []tables.CapHost, err error) {
	err = DB.Raw("select * from cap_host where cluster_id = ? and bind_user_id =0 "+
		" and locked_user_id=0 and id not in ( "+
		" select host_id from cap_session where cluster_id =? and status in ? )", clusterId, clusterId,
		[]int{tables.CapSessionStatusForInit, tables.CapSessionStatusForHolding, tables.CapSessionStatusForBreak}).
		Find(&li).Error
	return
}

// CountAppRunTimesByActionSession 统计应用在活跃会话中按主机ID计算启动次数
func (d sessionDao) CountAppRunTimesByActionSession(appName string, clusterId int64) (kvMap map[int64]int64, err error) {
	var li []cap.CountKv
	err = DB.Raw(" select host_id k,count(*) num  from cap_session_map_app where session_id in "+
		" (select id from cap_session where cluster_id = ? and status !=? ) and app_name = ?  group by host_id",
		clusterId, tables.CapSessionStatusForDestroyed, appName).Scan(&li).Error
	if err != nil {
		return
	}
	kvMap = make(map[int64]int64)
	for _, item := range li {
		kvMap[item.K] = item.Num
	}
	return
}

func (d sessionDao) FindLinkById(linkId int64) (lin tables.CapLink, err error) {
	err = DB.Model(&tables.CapLink{}).Where("id = ?", linkId).Find(&lin).Error
	return
}

func (d sessionDao) FindCertifyById(cid int64) (m tables.CapCertify, err error) {
	err = DB.Model(&tables.CapCertify{}).Where("id = ?", cid).Find(&m).Error
	return
}

func (d sessionDao) FindById(id int64) (m tables.CapSession, err error) {
	err = DB.Where(&tables.VapSession{Id: id}).Find(&m).Error
	return
}
func (d sessionDao) UpdateById(m tables.CapSession) (err error) {
	err = DB.Save(m).Error
	return err
}

func (d sessionDao) Page(in cap.SearchSessionForm) (li []tables.CapSession, total int64, err error) {
	tx := DB.Model(&tables.CapSession{})
	if in.Protocol != "" {
		tx.Where("protocol = ?", in.Protocol)
	}
	if in.HostId != 0 {
		tx.Where("host_id = ?", in.HostId)
	}
	if in.Status != 0 {
		tx.Where("status = ?", in.Status)
	}
	if in.StartTime != 0 {
		tx.Where("created_at between ? and ? ", in.StartTime, in.EndTime)
	}
	tx.Count(&total).Offset((in.PageNum - 1) * in.PageSize).Limit(in.PageSize).Find(&li)
	err = tx.Error
	return

}
